package cn.amaake.magicplugin.satoken.Interceptor;

import cn.amaake.magicplugin.satoken.config.MagicApiSaTokenConfig;
import cn.amaake.magicplugin.satoken.interfaces.SatokenUserInterface;
import cn.dev33.satoken.stp.StpUtil;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.context.ApplicationContext;
import org.ssssssss.magicapi.core.interceptor.RequestInterceptor;
import org.ssssssss.magicapi.core.model.ApiInfo;
import org.ssssssss.magicapi.core.model.JsonBean;
import org.ssssssss.magicapi.core.model.Options;
import org.ssssssss.magicapi.core.servlet.MagicHttpServletRequest;
import org.ssssssss.magicapi.core.servlet.MagicHttpServletResponse;
import org.ssssssss.script.MagicScriptContext;

import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;

public class CustomRequestInterceptor implements RequestInterceptor {

    private static final Logger logger = LoggerFactory.getLogger(CustomRequestInterceptor.class);

    private final MagicApiSaTokenConfig magicApiSaTokenConfig;

    private final ApplicationContext applicationContext;


    public CustomRequestInterceptor(MagicApiSaTokenConfig magicApiSaTokenConfig, ApplicationContext applicationContext){
        this.magicApiSaTokenConfig = magicApiSaTokenConfig;
        this.applicationContext = applicationContext;
    }

    /**
     * 接口请求之前
     * @param info	接口信息
     * @param context	脚本变量信息
     */
    @Override
    public Object preHandle(ApiInfo info, MagicScriptContext context, MagicHttpServletRequest request, MagicHttpServletResponse response) throws Exception {
        String id = StpUtil.getLoginIdByToken(request.getHeader(magicApiSaTokenConfig.getSaToken().getTokenName())).toString();

        logger.info("{} 请求接口：{}", id, info.getName());
        // 接口选项配置了需要登录
        if ("true".equals(info.getOptionValue(Options.REQUIRE_LOGIN))) {
            if (id == null) {
                return new JsonBean<>(401, "用户未登录");
            }
        }

        Class<?>  aClass = applicationContext.getBean(SatokenUserInterface.class).getClass();

        boolean roleboo;
        try {
            Method rolemethod = aClass.getDeclaredMethod("hasRole", String.class);
            roleboo = (boolean)rolemethod.invoke(applicationContext.getBean(SatokenUserInterface.class),id);
        } catch (NoSuchMethodException | IllegalAccessException | InvocationTargetException e) {
            throw new RuntimeException(e);
        }

        String role = info.getOptionValue(Options.ROLE);
        if (StringUtils.isNotBlank(role) && roleboo) {
            return new JsonBean<>(403, "用户权限不足");
        }

        boolean permissionboo;
        try {
            Method permissionmethod = aClass.getDeclaredMethod("hasPermission", String.class);
            permissionboo = (boolean)permissionmethod.invoke(applicationContext.getBean(SatokenUserInterface.class),id);
        } catch (NoSuchMethodException | IllegalAccessException | InvocationTargetException e) {
            throw new RuntimeException(e);
        }

        String permission = info.getOptionValue(Options.PERMISSION);
        if (StringUtils.isNotBlank(permission) && permissionboo) {
            return new JsonBean<>(403, "用户权限不足");
        }
        return null;
    }

    /**
     * 接口执行之后
     * @param info	接口信息
     * @param context	变量信息
     * @param returnValue 即将要返回到页面的值
     */
    @Override
    public Object postHandle(ApiInfo info, MagicScriptContext context, Object returnValue, MagicHttpServletRequest request, MagicHttpServletResponse response) throws Exception {
        logger.info("{} 执行完毕，返回结果:{}", info.getName(), returnValue);
        return null;
    }
}